<!--  -->
<template>
  <div class="biz-form-remote-select" :key="key">
    <el-select 
      :key="selectValueKey" 
      ref="BaseRemoteSelect" 
      v-el-select-loadmore="loadmoreOptions" 
      :popper-class="popperClass" 
      :clearable="showClearButton" 
      :collapsed="collapsed" 
      :collapse-tags="collapseTags" 
      :disabled="inputDisabled" 
      :loading="pending" 
      :multiple="isMulti" 
      :multiple-limit="multipleLimit" 
      :filterable="filterable" 
      :no-match-text="$t('common.base.tip.noData')" 
      :no-data-text="noDataText || $t('common.base.tip.noSearchData')" 
      remote 
      :remote-method="search" 
      :placeholder="placeholder" 
      :value="selectValue" 
      :value-key="valueKey" 
      @input="inputHandler" 
      @visible-change="visibleHandler">
      <el-option v-if="isShowSelect" v-for="(option, index) in optionList"  class="biz-remote-select-option" :key="option.value" :label="option.label" :value="option.value" :disabled="option.disabled">
        <slot name="option" :option="option"></slot>
      </el-option>
    </el-select>
  </div>
</template>

<script>
/* enum */
import EventNameEnum from '@model/enum/EventNameEnum';
import ComponentNameEnum from '@model/enum/ComponentNameEnum';
/* mixin */
import FormMixin from '@src/component/form/mixin/form';
/* model */
import Page from '@model/Page';
/* vue */
import { t } from '@src/locales';
/* scss */
import '@src/component/business/BizRemoteSelect/BizRemoteSelect.scss';
/* util */
import Log from '@src/util/log.ts';
import { uuid } from 'pub-bbx-utils';
import { isEmpty, isObject, isUndefined } from '@src/util/type';
import { getSystemNormalSearchInputForLength } from '@model/utils/getSystemConfig';
export default {
  mixins: [FormMixin],
  name: ComponentNameEnum.BizRemoteSelect,
  props: {
    isShowSelect: {
      type: Boolean,
      default: true,
    },
    collapsed: {
      type: Boolean,
      default: false,
    },
    collapseTags: {
      type: Boolean,
      default: false,
    },
    cleared: {
      type: Boolean,
      default: false,
    },
    inputDisabled: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    filterable: {
      type: Boolean,
      default: true,
    },
    options: {
      type: Array,
      default: () => [],
    },
    placeholder: {
      type: String,
      default: '',
    },
    remoteMethod: {
      type: Function,
      default: () => ({}),
    },
    value: {
      type: Array,
      default: () => [],
    },
    multipleLimit: {
      type: Number,
      default: 0,
    },
    keywordLengthLimit: {
      type: Boolean,
      default: false,
    },
    valueKey: {
      type: String,
      default: 'value',
    },
    // 是否在mounted时获取数据列表
    mountedSearch: {
      type: Boolean,
      default: false,
    },
    noDataText: {
      type: String,
      default: '',
    },
    popperClass: {
      type: String,
      default: '',
    },
  },
  computed: {
    isMulti() {
      return !isUndefined(this.multiple) && this.multiple !== false;
    },
    optionList() {
      let value = [];
      let isOptionsEmpty = isEmpty(this.options);
			if (!this.showSearchList && isEmpty(this.page.list)){
				value = this.value || []
			}else if (!isOptionsEmpty) {
        value = this.options || [];
      } else {
        value = this.page.list || [];
      }
      return value;
    },
    selectValueKey() {
      return `selectKey_${uuid()}`
    },
    selectValue() {
      // 多选
      if (this.isMulti) {
        return (
          this.value
            ?.map(item => {
              // 对象只取value
              if (isObject(item)) {
                return item[this.valueKey || ''];
              }

              return item;
            })
            .filter(item => Boolean(item)) || []
        );
      }
      // 单选
      let data = this.value?.[0] || {};
      let value = data[this.valueKey || ''] || data.id;

      return value;
    },
    showClearButton() {
      return Boolean(this.cleared && this.value && this.value?.length > 0 && !this.inputDisabled);
    },
  },
  data() {
    return {
      loadmoreOptions: {
        disabled: false,
        callback: this.loadmore,
        distance: 10,
      },
      pending: false,
      page: new Page(),
      keyword: '',
      showSearchList: false,
      key:1,
    };
  },
  watch: {
    value: {
      handler(newValue) {
        if(newValue?.length && this.mountedSearch){
          this.dispatchSearch()
        }
      },
      immediate: true,
    },
  },

  methods: {
    async dispatchSearch(){
      await this.search();
      // this.$forceUpdate();
      this.key++;
    },

    inputHandler(value) {
      let data = [];
      // 多选
      if (this.isMulti) {
        // 根据valuekey 返回原始数据
        let optionValue = '';
        data = this.optionList.filter(option => {
          optionValue = option[this.valueKey || ''];
          return value.indexOf(optionValue) >= 0;
        });
        if (Array.isArray(value)) {
          const notInListValues = value.filter(v => !this.optionList.find(option => option.value === v));
          const notInList = this.value?.filter(item => notInListValues.find(v => item.value === v)) || [];
          data = data.concat(notInList);
        }
      } else {
        data = this.optionList.filter(item => item?.id === value || item?.value === value);
      }

      this.$emit(EventNameEnum.Input, data);
    },
    fetchRemoteData(params, keyword) {
      if (!this.remoteMethod) return null;
      // 联想搜索长度受系统搜索长度限制
      if (this.keywordLengthLimit) {
        keyword = getSystemNormalSearchInputForLength(keyword);
      }
      // 页面信息
      const { pageNum, pageSize } = this.page;
      const searchParams = params || { keyword, pageNum, pageSize };
      return this.remoteMethod(searchParams)
        .then(result => {
          this.pending = false;
          this.loadmoreOptions.disabled = Boolean(!result?.hasNextPage);
          return result;
        })
        .catch(error => {
          this.pending = false;
          Log.error(error, this.search.name);
        });
    },
    getAttributes() {
      return {
        directives: [
          {
            name: 'loading',
            value: this.pending,
          },
        ],
      };
    },
    async loadmore() {
      if (this.pending || this.loadmoreOptions.disabled) return;

      this.loadmoreOptions.disabled = true;
      this.pending = true;

      try {
        this.page.pageNum += 1;
        const result = await this.fetchRemoteData(null, this.keyword);
        this.page.merge(result);
      } catch (error) {
        Log.error(error, this.loadmore.name);
      }
    },
    async search(keyword = '', params = null, showloading = true) {
      if (!this.remoteMethod) return;
      if (this.pending) return;

      this.keyword = keyword;

      // 初始化page对象
      this.page = new Page();
      // 获取远程数据
      showloading && (this.pending = true);
      try {
        await this.fetchRemoteData(null, keyword).then(data => {
          this.page.cover(data);
        });
      } catch (err) {}
    },
    visibleHandler(visible) {
      this.showSearchList = visible;
			this.optionList
      if (visible) return this.search('', null, false);

      // this.page.list = [];
      this.keyword = '';
    },
    outsideSearch(keyword = '', params = null) {
      this.pending = true;
      // 初始化page对象
      this.page = new Page();
      // 获取远程数据
      this.fetchRemoteData(params, keyword).then(data => {
        this.page.cover(data);
      });
      // this.search(keyword, params)
    },
  },
};
</script>
<style lang="scss" scoped>
@import './BizRemoteSelect.scss';
</style>
